import hashlib
import os
import glob2
import sys
import codecs
import chardet


class FileHandler:

    @staticmethod
    def abstract(file_path, byte_size=1024):
        """
        获取文件的哈希值
        :param file_path: 文件路径
        :param byte_size: 每次读取的字节大小
        :return:
        """
        # 检测文件是否存在
        if not FileHandler.exists_file(file_path):
            raise ValueError("文件不存在")

        md5_1 = hashlib.md5()  # 创建一个md5算法对象
        with open(file_path, 'rb') as f:  # 打开一个文件，必须是'rb'模式打开
            while 1:
                data = f.read(byte_size)  # 由于是一个文件，每次只读取固定字节
                if data:  # 当读取内容不为空时对读取内容进行update
                    md5_1.update(data)
                else:  # 当整个文件读完之后停止update
                    break
        print("读取完毕")
        ret = md5_1.hexdigest()  # 获取这个文件的MD5值
        print("计算MD5完毕")
        return ret

    @staticmethod
    def exists_file(file_path):
        """
        检测文件是否存在
        :param file_path:
        :return:
        """
        if os.path.exists(file_path):
            return os.path.isfile(file_path)
        else:
            return False

    @staticmethod
    def exists_dictionary(dictionary_path):
        """
        检测文件是否存在
        :param dictionary_path:
        :return:
        """
        if os.path.exists(dictionary_path):
            return not os.path.isfile(dictionary_path)
        else:
            return False

    @staticmethod
    def get_metadata(file_path):
        pass

    @staticmethod
    def get_file_size(file_path):
        """
        获取文件大小
        :param file_path: 文件路径
        :return: 字节数，文件不存在则返回0
        """
        if FileHandler.exists_file(file_path):
            return os.path.getsize(file_path)
        else:
            return 0

    @staticmethod
    def get_dictionary_size(dictionary_path):
        """
        获取文件大小
        :param dictionary_path: 文件路径
        :return: 字节数，文件不存在则返回0
        """
        total_size = 0
        if FileHandler.exists_dictionary(dictionary_path):
            filename = os.walk(dictionary_path)
            for root, dirs, files in filename:
                for fle in files:
                    size = os.path.getsize(dictionary_path + fle)
                    total_size += size
        return total_size

    @staticmethod
    def dir_has_file(path, file_type="*"):
        """
        提取文件夹下所有指定类型的文件
        :param path:
        :param file_type:
        :return:
        """
        return glob2.glob(path + '/**/*' + str(".") + file_type, recursive=True)

    @staticmethod
    def translateEncode(path, out_path, encoding='utf-8'):
        (floders, files) = FileHandler.list_folders_files(path)
        for file in files:
            file_name = os.path.join(path, file)
            print(file_name)
            # try:
            with open(file_name, "rb") as f_in:
                    data = f_in.read()
                    code_type = chardet.detect(data)['encoding']
                    print(code_type)
                    FileHandler.convert(file_name, file, out_path, code_type, encoding)
            # except IOError as err:
            #     print(err)

    @staticmethod
    def convert(file_name, file, out_path, in_code="GBK", out_code="UTF-8"):
        """
        该程序用于将目录下的文件从指定格式转换到指定格式，默认的是GBK转到UTF-8
        :param file:    文件路径
        :param in_code:  输入文件格式
        :param out_code: 输出文件格式
        :return:
        """
        with codecs.open(file_name, 'r', in_code) as f_in:
                new_content = f_in.read()
                f_out = codecs.open(os.path.join(out_path, file), 'w', out_code)
                f_out.write(new_content)
                f_out.close


    @staticmethod
    def list_folders_files(path):
        """
        返回 "文件夹" 和 "文件" 名字

        :param path: "文件夹"和"文件"所在的路径
        :return:  (list_folders, list_files)
                :list_folders: 文件夹
                :list_files: 文件
        """
        list_folders = []
        list_files = []
        for file in os.listdir(path):
            file_path = os.path.join(path, file)
            if os.path.isdir(file_path):
                list_folders.append(file)
            else:
                list_files.append(file)
        return (list_folders, list_files)
